#include "serial.h"
#include "ui_serial.h"

serial::serial(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::serial)
{
    ui->setupUi(this);

    /* 初始化串口 */
    this->on_pushButton_refresh_clicked();//初始化清除串口
    m_serial.close();//初始化关闭串口
    ui->pushButton_open->setStyleSheet("background-color: rgb(0,255,0)");
    ui->pushButton_open->setText("打开");

    /* 刷新串口的定时器设置 */
    m_serialTimer = new QTimer(this);
    m_serialTimer->setInterval(5000);
    m_serialTimer->start();
    connect(m_serialTimer, &QTimer::timeout, this, &serial::on_pushButton_refresh_clicked);

    /* 设置波形显示窗口属性 */
    /* 1、左轮波形窗口属性 */
    ui->customPlot_leftmotor->addGraph();//添加曲线
    ui->customPlot_leftmotor->graph(0)->setPen(QPen(Qt::blue));//曲线颜色
    //让范围自行缩放
    ui->customPlot_leftmotor->graph(0)->rescaleAxes();
    //允许用户用鼠标拖动轴范围，用鼠标滚轮缩放，点击选择图形
    ui->customPlot_leftmotor->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    mData = QSharedPointer<QCPGraphDataContainer>(new QCPGraphDataContainer);
    ui->customPlot_leftmotor->graph()->setData(mData);

    /* 2、右轮波形窗口属性 */
    ui->customPlot_rightmotor->addGraph();//添加曲线
    ui->customPlot_rightmotor->graph(0)->setPen(QPen(Qt::blue));//曲线颜色
    //让范围自行缩放
    ui->customPlot_rightmotor->graph(0)->rescaleAxes();
    //允许用户用鼠标拖动轴范围，用鼠标滚轮缩放，点击选择图形
    ui->customPlot_rightmotor->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    /* 3、偏航角波形窗口属性 */
    ui->customPlot_yaw->addGraph();//添加曲线
    ui->customPlot_yaw->graph(0)->setPen(QPen(Qt::blue));//曲线颜色
    //让范围自行缩放
    ui->customPlot_yaw->graph(0)->rescaleAxes();
    //允许用户用鼠标拖动轴范围，用鼠标滚轮缩放，点击选择图形
    ui->customPlot_yaw->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    /* 4、俯仰角波形窗口属性 */
    ui->customPlot_pitch->addGraph();//添加曲线
    ui->customPlot_pitch->graph(0)->setPen(QPen(Qt::blue));//曲线颜色
    //让范围自行缩放
    ui->customPlot_pitch->graph(0)->rescaleAxes();
    //允许用户用鼠标拖动轴范围，用鼠标滚轮缩放，点击选择图形
    ui->customPlot_pitch->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);


}

serial::~serial()
{
    delete ui;
}

/* 刷新串口 */
void serial::on_pushButton_refresh_clicked()
{
    //清除串口
    ui->comboBox_port->clear();
    //遍历串口信息
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->comboBox_port->addItem(info.portName());
    }
}

/* 打开串口 */
void serial::on_pushButton_open_clicked()
{
    if(m_serial.isOpen())//如果串口处于打开状态，点下去就关闭
    {
        ui->pushButton_open->setStyleSheet("background-color: rgb(0,255,0)");
        ui->pushButton_open->setText("打开");
        m_serial.close();
    }
    else//如果串口处于关闭状态，点下去就打开
    {
        ui->pushButton_open->setStyleSheet("background-color: rgb(255,0,0)");
        ui->pushButton_open->setText("关闭");
        m_serial.setPortName(ui->comboBox_port->currentText());//串口号
        m_serial.setBaudRate(ui->comboBox_baud->currentText().toInt());//波特率
        m_serial.setDataBits(QSerialPort::Data8);//数据位
        m_serial.setParity(QSerialPort::NoParity);//校验位
        m_serial.setStopBits(QSerialPort::OneStop);//停止位
        m_serial.open(QIODevice::ReadWrite);
        connect(&m_serial, &QSerialPort::readyRead, this, &serial::messlot);//链接到信息处理函数
    }
}

/* 串口接受信息的处理函数 */
void serial::messlot()
{
    QString recv_buf = m_serial.readAll();//接受缓存
    static double data_x=0.0;
    static QString sumData;
    if(!recv_buf.isEmpty())
    {
        sumData.append(recv_buf);
        if(sumData.contains("\n"))//检测到换行符
        {
            data_x+=dt;//x轴自增
            ui->plainTextEdit_receive->insertPlainText(sumData);//文本显示接受到的信息

            QStringList buffs = sumData.split("/");//串口端发送数据格式：          data1/data2/data3/data4/ProtectFrame(最后一个加个保护帧是为了减小数据错误概率)
            int list_count = buffs.count();
            if(list_count == 5)
            {
                customplot_leftmotor_paint(data_x, buffs[0]);//左轮速度绘制

                customplot_rightmotor_paint(data_x, buffs[1]);//右轮速度绘制

                customplot_yaw_paint(data_x, buffs[2]);//偏航角绘制

                customplot_pitch_paint(data_x, buffs[3]);//俯仰角绘制
            }
            ui->plainTextEdit_receive->verticalScrollBar()->setSliderPosition(ui->plainTextEdit_receive->verticalScrollBar()->maximum());//接收窗口滚动条滑倒最底部
            sumData.clear();
            buffs.clear();
        }
    }
    recv_buf.clear();
}

/* 清除串口数据 */
void serial::on_pushButton_clearrecevice_clicked()
{
    ui->plainTextEdit_receive->clear();
}

/* 左轮速度绘制 */
void serial::customplot_leftmotor_paint(double data_x, QString data)
{
    double temp=data.toDouble();
    arrX_left.append(data_x);
    arrY_left.append(temp);

    ui->customPlot_leftmotor->graph(0)->setData(arrX_left,arrY_left);
    ui->customPlot_leftmotor->replot();
    if(data_x>(X_max*dt))
          ui->customPlot_leftmotor->xAxis->setRange(data_x-(X_max*dt),data_x);//调整x轴，跟随滑动
    ui->customPlot_leftmotor->yAxis->rescale(true);//自动调整y轴
}

/* 右轮速度绘制 */
void serial::customplot_rightmotor_paint(double data_x, QString data)
{
    double temp=data.toDouble();
    arrX_right.append(data_x);
    arrY_right.append(temp);

    ui->customPlot_rightmotor->graph(0)->setData(arrX_right,arrY_right);
    ui->customPlot_rightmotor->replot();
    if(data_x>(X_max*dt))
          ui->customPlot_rightmotor->xAxis->setRange(data_x-(X_max*dt),data_x);//调整x轴，跟随滑动
    ui->customPlot_rightmotor->yAxis->rescale(true);//自动调整y轴
}

/* 偏航角绘制 */
void serial::customplot_yaw_paint(double data_x, QString data)
{
    double temp=data.toDouble();
    arrX_yaw.append(data_x);
    arrY_yaw.append(temp);

    ui->customPlot_yaw->graph(0)->setData(arrX_yaw,arrY_yaw);
    ui->customPlot_yaw->replot();
    if(data_x>(X_max*dt))
          ui->customPlot_yaw->xAxis->setRange(data_x-(X_max*dt),data_x);//调整x轴，跟随滑动
    ui->customPlot_yaw->yAxis->rescale(true);//自动调整y轴
}

/* 俯仰角绘制 */
void serial::customplot_pitch_paint(double data_x, QString data)
{
    double temp=data.toDouble();
    arrX_pitch.append(data_x);
    arrY_pitch.append(temp);

    ui->customPlot_pitch->graph(0)->setData(arrX_pitch,arrY_pitch);
    ui->customPlot_pitch->replot();
    if(data_x>(X_max*dt))
          ui->customPlot_pitch->xAxis->setRange(data_x-(X_max*dt),data_x);//调整x轴，跟随滑动
    ui->customPlot_pitch->yAxis->rescale(true);//自动调整y轴
}


void serial::on_pushButton_setPID_clicked()
{
    QString Data_Mechanical = ui->lineEdit_Mechanical->text();
    QString Data_VerticalKp = ui->lineEdit_VerticalKp->text();
    QString Data_VerticalKd = ui->lineEdit_VerticalKd->text();
    QString Data_SpeedKp = ui->lineEdit_SpeedKp->text();
    QString Data_SpeedKi = ui->lineEdit_SpeedKi->text();
    QString Data_AngleKp = ui->lineEdit_AngleKp->text();

    /* 未输入数据主动变为0.0 */
    if(Data_Mechanical == "")
        Data_Mechanical = "0.0";
    if(Data_VerticalKp == "")
        Data_VerticalKp = "0.0";
    if(Data_VerticalKd == "")
        Data_VerticalKd = "0.0";
    if(Data_SpeedKp == "")
        Data_SpeedKp = "0.0";
    if(Data_SpeedKi == "")
        Data_SpeedKi = "0.0";
    if(Data_AngleKp == "")
        Data_AngleKp = "0.0";

    qDebug()<<"Data_Mechanical:"<<Data_Mechanical<<endl;
    qDebug()<<"Data_VerticalKp:"<<Data_VerticalKp<<endl;
    qDebug()<<"Data_VerticalKd:"<<Data_VerticalKd<<endl;
    qDebug()<<"Data_SpeedKp:"<<Data_SpeedKp<<endl;
    qDebug()<<"Data_SpeedKi:"<<Data_SpeedKi<<endl;
    qDebug()<<"Data_AngleKp:"<<Data_AngleKp<<endl;

    /* 发送数据格式为："data1/data2/data3/data4/data5/data6\r\n" */
    QString temp = QString("%1/%2/%3/%4/%5/%6\r\n").arg(Data_Mechanical).arg(Data_VerticalKp).arg(Data_VerticalKd).arg(Data_SpeedKp).arg(Data_SpeedKi).arg(Data_AngleKp);
    QByteArray sendbuf = temp.toLocal8Bit();
    m_serial.write(sendbuf);
}
